﻿//  Copyright (c) 2011 Ray Liang (http://www.dotnetage.com)
//  Licensed MIT: http://www.opensource.org/licenses/mit-license.php

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DNA.Mvc.Data.Entity
{
    public class WidgetDescriptorRepository : EntityRepository<WidgetDescriptor>, IWidgetDescriptorRepository
    {
        public WidgetDescriptorRepository() : base() { }

        public WidgetDescriptorRepository(DB dbContext) : base(dbContext) { }

        public virtual void Delete(int id)
        {
            if (id <= 0) throw new ArgumentOutOfRangeException("id");
            this.Delete(Find(id));
        }

        public virtual void Delete(string installedPath)
        {
            if (string.IsNullOrEmpty(installedPath)) throw new ArgumentNullException("installedPath");
            this.Delete(Find(installedPath));
        }

        public virtual WidgetDescriptor Find(string controllerName, string action)
        {
            return Find(w => (w.Controller == controllerName && w.Action == action));
        }

        public virtual WidgetDescriptor Find(string installedPath)
        {
            if (string.IsNullOrEmpty(installedPath)) throw new ArgumentNullException("installedPath");
            return Find(w => (w.InstalledPath.Equals(installedPath, StringComparison.OrdinalIgnoreCase)));
        }

        public virtual IEnumerable<WidgetDescriptor> WithInPath(string path)
        {
            if (string.IsNullOrEmpty(path)) throw new ArgumentNullException("path");
            Context.Configuration.ProxyCreationEnabled = false;
            return Filter(w => w.InstalledPath.Contains(path));
        }

        public virtual int InusingWidgetsCount(string installedPath)
        {
            if (string.IsNullOrEmpty(installedPath)) throw new ArgumentNullException("installedPath");
            var descriptor = Find(installedPath);
            if (descriptor == null)
                return 0;
            return ((DB)Context).Widgets.Count(w => w.DescriptorID == descriptor.ID);
        }

        public virtual WidgetDescriptor Create(WidgetTemplate template, string installedPath)
        {
            #region For common properties

            var descriptor = new WidgetDescriptor()
            {
                Description = template.Description,
                InstalledPath = installedPath,
                Version = template.Version,
                Title = template.Name, // string.IsNullOrEmpty(tmpl.Defaults.Title) ? tmpl.Name : tmpl.Defaults.Title,
                IconUrl = template.Icons.Count > 0 ? ResolveInstalledPathUrl(template.Icons[0].Source, installedPath) : "",
                ImageUrl = template.Icons.Count > 1 ? ResolveInstalledPathUrl(template.Icons[1].Source, installedPath) : "",
                //Action = tmpl.Defaults.Action,
                ContentType = template.Content.ContentType,
                ContentUrl = ResolveInstalledPathUrl(template.Content.Source, installedPath),
                ShowBorder = true,
                ShowHeader = true,
                Modified = template.Modified
            };

            if (template.UserPreferences.Count > 0)
            {
                var properties = new Dictionary<string, object>();
                foreach (WidgetUserPreference userPreperence in template.UserPreferences)
                {
                    var valueType = typeof(string);
                    Type typeDef = null;
                    if (!string.IsNullOrEmpty(userPreperence.Type))
                        typeDef = Type.GetType(userPreperence.Type);
                    object value = (typeDef != null) ? Convert.ChangeType(userPreperence.Value, typeDef) : "";
                    properties.Add(userPreperence.Name, value);
                }
                descriptor.Properties = properties;
            }
            #endregion

            #region From dna extension <defaults>

            if (!string.IsNullOrEmpty(template.Defaults.Title))
                descriptor.Title = template.Defaults.Title;

            descriptor.TitleLinkUrl = template.Defaults.TitleLinkUrl;

            if (!string.IsNullOrEmpty(template.Defaults.IconUrl))
                descriptor.IconUrl = ResolveInstalledPathUrl(template.Defaults.IconUrl, installedPath);
            descriptor.ShowBorder = template.Defaults.ShowBorder;
            descriptor.ShowHeader = template.Defaults.ShowHeader;
            descriptor.Area = template.Defaults.Area;
            descriptor.Controller = template.Defaults.Controller;
            descriptor.IsClosable = true;
            descriptor.IsDeletable = true;
            descriptor.Action = template.Defaults.Action;

            #endregion

            return Create(descriptor);
        }

        public virtual WidgetDescriptor Update(WidgetTemplate template, WidgetDescriptor descriptor)
        {
            #region For common properties

            descriptor.Description = template.Description;
            descriptor.Version = template.Version;
            descriptor.Title = string.IsNullOrEmpty(template.Defaults.Title) ? template.Name : template.Defaults.Title;
            descriptor.IconUrl = template.Icons.Count > 0 ? ResolveInstalledPathUrl(template.Icons[0].Source, descriptor.InstalledPath) : "";
            descriptor.ImageUrl = template.Icons.Count > 1 ? ResolveInstalledPathUrl(template.Icons[1].Source, descriptor.InstalledPath) : "";
            descriptor.ContentType = template.Content.ContentType;
            descriptor.ContentUrl = ResolveInstalledPathUrl(template.Content.Source, descriptor.InstalledPath);
            descriptor.Modified = template.Modified;

            if (template.UserPreferences.Count > 0)
            {
                if ((descriptor.Properties != null) && (descriptor.Properties.Count > 0))
                    descriptor.Properties.Clear();

                var properties = new Dictionary<string, object>();
                foreach (WidgetUserPreference userPreperence in template.UserPreferences)
                {
                    var valueType = typeof(string);
                    Type typeDef = null;
                    if (!string.IsNullOrEmpty(userPreperence.Type))
                        typeDef = Type.GetType(userPreperence.Type);
                    object value = (typeDef != null) ? Convert.ChangeType(userPreperence.Value, typeDef) : "";
                    properties.Add(userPreperence.Name, value);
                }
                descriptor.Properties = properties;
            }
            #endregion

            #region From dna extension <defaults>

            if (!string.IsNullOrEmpty(template.Defaults.Title))
                descriptor.Title = template.Defaults.Title;

            descriptor.TitleLinkUrl = template.Defaults.TitleLinkUrl;

            if (!string.IsNullOrEmpty(template.Defaults.IconUrl))
                descriptor.IconUrl = ResolveInstalledPathUrl(template.Defaults.IconUrl, descriptor.InstalledPath);
            descriptor.ShowBorder = template.Defaults.ShowBorder;
            descriptor.ShowHeader = template.Defaults.ShowHeader;
            descriptor.Area = template.Defaults.Area;
            descriptor.Controller = template.Defaults.Controller;
            descriptor.IsClosable = true;
            descriptor.IsDeletable = true;
            descriptor.Action = template.Defaults.Action;

            var widgets = descriptor.Widgets;
            foreach (var widget in widgets)
            {
                widget.Action = descriptor.Action;
                widget.Controller=descriptor.ControllerShortName;
                widget.ContentUrl = descriptor.ContentUrl;
                widget.Area = descriptor.Area;
            }
            #endregion

            return Update(descriptor);
        }

        private string ResolveInstalledPathUrl(string vPath, string installedPath)
        {
            if (!string.IsNullOrEmpty(vPath))
            {
                if (!vPath.StartsWith("~") && !vPath.StartsWith("/"))
                    return "~/content/widgets/" + installedPath.Replace("\\", "/") + "/" + vPath;
                else
                    return vPath;
            }
            return "";
        }
    }
}
